/**
 * 
 */
package org.ranch.model;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;

/**
 * represents a farm
 * 
 */
@Entity
@Table(name = "farm")
public class Farm extends BaseData implements Comparable<Farm> {

    /** farm name */
    private String name;
    /** Farm address */
    private Address address;
    /** Kraals at the farm */
    private List<Kraal> kraals;
    /** Farm manager */
    private Person manager;

    /** Default constructor */
    public Farm() {
	super();
    }

    public Farm(String name, Address address, List<Kraal> kraals, Person manager) {
	super();
	setName(name);
	setAddress(address);
	setKraals(kraals);
	setManager(manager);
    }

    /**
     * gets the address of the farm.
     * 
     * @return the address
     */
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "address_id")
    public Address getAddress() {
	return address;
    }

    /**
     * Sets the address of the farm
     * 
     * @param address
     */
    public void setAddress(Address address) {
	this.address = address;
    }

    /**
     * Gets the kraals in this farm
     * 
     * @return
     */

    @SuppressWarnings("deprecation")
    @OneToMany(mappedBy = "farm")
    @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE,
	    org.hibernate.annotations.CascadeType.DELETE,
	    org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
    public List<Kraal> getKraals() {
	return kraals;
    }

    /**
     * Sets the kraal
     * 
     * @param kraals
     */
    public void setKraals(List<Kraal> kraals) {
	this.kraals = kraals;
    }

    /**
     * Gets the farm manager
     * 
     * @return
     */
    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    @JoinColumn(name = "person", nullable = true)
    public Person getManager() {
	return manager;
    }

    /**
     * Sets the farm manager
     * 
     * @param manager
     */
    public void setManager(Person manager) {
	this.manager = manager;
    }

    /**
     * Gets the farm name
     * 
     * @return
     */
    @Column(name = "farm_name", nullable = false)
    public String getName() {
	return name;
    }

    /**
     * Sets the farm name
     * 
     * @param name
     */
    public void setName(String name) {
	this.name = name;
    }

    public int compareTo(Farm o) {
	return this.getName().compareToIgnoreCase(o.getName());
    }

    /**
     * adds a given kraal to the farm
     * 
     * @param kraal
     */
    public void addKraal(Kraal kraal) {
	if (kraal == null) {
	    return;
	}

	if (getKraals() == null) {
	    setKraals(new ArrayList<Kraal>());
	}

	getKraals().add(kraal);
	kraal.setFarm(this);
    }

    /**
     * removes a given kraal from the farm
     * 
     * @param kraal
     */
    public void removeKraal(Kraal kraal) {
	if (kraal == null || getKraals() == null) {
	    return;
	}

	getKraals().remove(kraal);
    }
}
